Sinus und Logarithmus goes Assembler...

← Zurück zum Forum

... ganz bestimmt, aber hier erstmal ohne mich!!

Ich habe mich jetzt etwas näher mit dem Cordic- und dem BKM-Algorithmus beschäftigt. BKM mathematisch für die Berechnung von Logarithmus sinnvoll und gut, relativ kompliziert, Umsetzung in Assembler möglich... Cordic für Sinus / Cosinus und noch etliche andere Dinge gut.... Bei beiden braucht man aber auch Tabellen mit vorberechneten Werten, am besten alles in Floating Point.... ist mir ehrlich gesagt zu aufwendig. Braucht man Sin/Cos - dann baue ich mir eine Tabelle und gut ist. Gleiches gilt für den Logarithmus.

Und alles andere haben wir jetzt: Addition, Subtraktion, Multiplikation, Division, Quadrat, Quadratwurzel und Pythagoras....

Moin!

Ja, ist sicherlich für die Spiele-Programmierung mit Tabellen sinnvoller. Da gibt es so viele Themen, die ins Wiki gehören... wenn zum Schluss Langeweile auftritt, kann man es immer noch einpflegen 😉

Grüße Janko

Meine Projekte findest Du hier...

. Hallo Leute

Ist bei den Sachen von Dieter "Old Man Tower" Gretzschel nicht was brauchbares dabei? Als Routine oder als Ansatz für eine Routine? Dieter war Mathe-Lehrer.

Tschüß

Mathy

Schreibe nicht der Absicht zu, was man mit Dummheit oder Ignoranz erklären kann.

Mathe != Programmieren.

Mathe hilft beim Programmieren, aber rechnen mit Binärzahlen (und das schnell) ist eine andere Disziplin als Mathe (Algebra) verstehen.

Dieter hat seine (tollen) Programme in Basic geschrieben, Basic hilft wenig wenn man (schnelle) Assembler-Umsetzungen haben möchte.

https://mastodon.social/@cstrotm https://abbuc.social

Danke für den Link, Carsten! Sehr komplex und sehr umfangreich. Ich denke für echte mathematische Berechnungen incl. Fließkomma braucht man die Routinen. Für Spiele reichen wahrscheinlich Näherungen mit Look-Up Tabellen aus. Der menschlichen Kreativität auch hinsichtlich effektiven Näherungen scheint dabei keinen Grenzen gesetzt zu sein. Gestern bin ich bei meinen Recherchen auf einen recht neuen Algorithmus gestossen: Dem "fast inverse square root" Algorithmus. Der scheint recht kompakt und klein, ist aber wohl fast bahnbrechend für 3D-Spiele und wurde entsprechend gefeiert. Dieser Algorithmus liefert die Berechnung von 1/Wurzel x und damit werden Vektoren normalisiert. Das ist für jede 3D Berechnung notwendig, wenn man bei heutigen komplexen 3D Spielen von Millionen Berechnungen ausgeht, dann sind solche schnellen Algorithmen sofort spürbar. Dieser neue Algorithmus soll schneller sein, als Look-up Tabellen.

Und so sieht er aus:

float q_rsqrt(float number)
{
  long i;
  float x2, y;
  const float threehalfs = 1.5F;
  x2 = number * 0.5F;
  y  = number;
  i  = * ( long * ) &y;                       // evil floating point bit level hacking
  i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
  y  = * ( float * ) &i;
  y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
  // y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

  return y;
}

Das "Wunder" ist dabei die Konstante 0x5f3759df in Dezimal 1,597,463,007 Die vollbringt wohl das notwendige Bit-Shifting für die 1/Wurzel x Berechnung....

Und nun doch noch eine kleine aber feine Routine für sin und cos von Lee Davison:

        ; SIN/COS Tabelle - liefert Werte zwischen $0000 und $7FFF

sintab
        .word $0000,$0324,$0647,$096A,$0C8B,$0FAB,$12C8,$15E2
        .word $18F8,$1C0B,$1F19,$2223,$2528,$2826,$2B1F,$2E11
        .word $30FB,$33DE,$36BE,$398C,$3C56,$3F17,$41CE,$447A
        .word $471C,$49B4,$4C3F,$4EBF,$5133,$539B,$55F5,$5842
        .word $5A82,$5CB4,$5ED7,$60EC,$62F2,$64EB,$66CF,$68A6
        .word $6A6D,$6C24,$6DC4,$6F5F,$70E2,$7255,$73B5,$7504
        .word $7641,$776C,$7884,$798A,$7A7D,$7B5D,$7C2A,$7CE3
        .word $7D8A,$7E1D,$7E9D,$7F09,$7F62,$7FA7,$7FD8,$7FF6
        .word $7FFF


        .proc main
        ;----------------------------------------------------------------   
        ;
        ; SIN(A) COS(A) routines. A full circle is represented by $00 to
        ; $00 in 256 1.40625 degree steps. returned value is signed 16
        ; bit with X being the high byte and ranges over +/-0.99997

        ; The routine never returns +1.0 as it is out of the range of the
        ; returned value. The routine also never returns -1.0 as, although
        ; it is in range, the calculation is symetrical for both positive
        ; and negative results.
        ;....................... Sin/Cos .......

        ; COS(A) in AX

cos_A
        CLC                     ; clear carry for add
        ADC   #$40              ; add 1/4 rotation

        ;----------------------------------------------------------------
        ;
        ; get SIN(A) in AX. enter with the Z flag reflecting the contents
        ; of A

sin_A
        BPL   sin_cos           ; just get SIN/COS and return if +ve

        AND   #$7F              ; else make +ve
        JSR   sin_cos           ; get SIN/COS
                              ; now do twos complement
        EOR   #$FF              ; toggle the low byte
        CLC                     ; clear carry for add
        ADC   #$01              ; add 1 to the low byte
        PHA                     ; save the low byte
        TXA                     ; copy the high byte
        EOR   #$FF              ; toggle the high byte
        ADC   #$00              ; add the carry from the low byte
        TAX                     ; copy back to X
        PLA                     ; restore the low byte
        RTS

        ;----------------------------------------------------------------
        ;
        ; get AX from SIN/COS table

sin_cos
        CMP   #$41              ; compare with max+1
        BCC   quadrant          ; branch if less

        EOR   #$7F              ; wrap $41 to $7F ..
        ADC   #$00              ; .. to $3F to $00
quadrant
        ASL                     ; * 2 bytes per value
        TAX                     ; copy to index
        LDA   sintab,X          ; get SIN/COS table value low byte
        PHA                     ; save it
        LDA   sintab+1,X        ; get SIN/COS table value high byte
        TAX                     ; copy to X
        PLA                     ; restore the low byte
        RTS

@ Carsten: Ich brauche noch eine kleine Anweisung, wie ich im Atari-Wiki neue Seiten erstelle...

Dr. Irata schrieb: @ Carsten: Ich brauche noch eine kleine Anweisung, wie ich im Atari-Wiki neue Seiten erstelle...

Hallo Peter,

Du erstellt auf irgendeiner Seite einen Link auf eine Seite welche noch nicht existiert (z.B. im LeftMenu, aber geht auf jeder Seite):

Anzeige Text

Der Name der neuen Seite ist in den runden Klammern. Dabei empfehle ich:

  • Nur ASCII Zeichen im Seiten Namen (der Anzeigetext darf alle Unicode-Zeichen beinhalten)
  • Keine Leerzeichen
  • Nicht mit Ziffern beginnen
  • Ein Seitenname kann später nur schwer geändert werden, daher vorher über einen guten Namen nachdenken

Danach wird ein Link auf eine noch nicht existierende Seite in "rot" dargestellt. Dann auf diesen Link klicken und die Seite füllen. Beim ersten Speichern wird die Seite erstellt.

https://mastodon.social/@cstrotm https://abbuc.social

Hallo Carsten... jetzt klappt es, tak!! Das Leerzeichen war zu viel 😉

Dr. Irata schrieb: Hallo Carsten... jetzt klappt es, tak!! Das Leerzeichen war zu viel ;-)

Das Markdown ist Commonmark: https://commonmark.org/

https://mastodon.social/@cstrotm https://abbuc.social